Next: Keymaps and Minor Modes, Up: Minor Modes [Contents][Index]
There are conventions for writing minor modes just as there
are for major modes. These conventions are described below. The
easiest way to follow them is to use the macro
define-minor-mode. See Defining Minor
Modes.
nil if the mode is
disabled, and non-nil if the mode is enabled.
The variable should be buffer-local if the minor mode is
buffer-local.
This variable is used in conjunction with the
minor-mode-alist to display the minor mode name
in the mode line. It also determines whether the minor mode
keymap is active, via minor-mode-map-alist (see
Controlling
Active Maps). Individual commands or hooks can also check
its value.
The mode command should accept one optional argument. If called interactively with no prefix argument, it should toggle the mode (i.e., enable if it is disabled, and disable if it is enabled). If called interactively with a prefix argument, it should enable the mode if the argument is positive and disable it otherwise.
If the mode command is called from Lisp (i.e.,
non-interactively), it should enable the mode if the argument
is omitted or nil; it should toggle the mode if
the argument is the symbol toggle; otherwise it
should treat the argument in the same way as for an
interactive call with a numeric prefix argument, as described
above.
The following example shows how to implement this behavior
(it is similar to the code generated by the
define-minor-mode macro):
(interactive (list (or current-prefix-arg 'toggle)))
(let ((enable (if (eq arg 'toggle)
(not foo-mode) ; this mode’s mode variable
(> (prefix-numeric-value arg) 0))))
(if enable
do-enable
do-disable))
The reason for this somewhat complex behavior is that it lets users easily toggle the minor mode interactively, and also lets the minor mode be easily enabled in a mode hook, like this:
(add-hook 'text-mode-hook 'foo-mode)
This behaves correctly whether or not
foo-mode was already enabled, since the
foo-mode mode command unconditionally enables
the minor mode when it is called from Lisp with no argument.
Disabling a minor mode in a mode hook is a little uglier:
(add-hook 'text-mode-hook (lambda () (foo-mode -1)))
However, this is not very commonly done.
minor-mode-alist for each
minor mode (see
Definition of minor-mode-alist), if you want to indicate
the minor mode in the mode line. This element should be a
list of the following form:
(mode-variable string)
Here mode-variable is the variable that controls enabling of the minor mode, and string is a short string, starting with a space, to represent the mode in the mode line. These strings must be short so that there is room for several of them at once.
When you add an element to minor-mode-alist,
use assq to check for an existing element, to
avoid duplication. For example:
(unless (assq 'leif-mode minor-mode-alist) (push '(leif-mode " Leif") minor-mode-alist))
or like this, using add-to-list (see List Variables):
(add-to-list 'minor-mode-alist '(leif-mode " Leif"))
In addition, several major mode conventions apply to minor modes as well: those regarding the names of global symbols, the use of a hook at the end of the initialization function, and the use of keymaps and other tables.
The minor mode should, if possible, support enabling and
disabling via Custom (see Customization). To do
this, the mode variable should be defined with
defcustom, usually with :type 'boolean.
If just setting the variable is not sufficient to enable the
mode, you should also specify a :set method which
enables the mode by invoking the mode command. Note in the
variable’s documentation string that setting the variable
other than via Custom may not take effect. Also, mark the
definition with an autoload cookie (see autoload cookie), and specify
a :require so that customizing the variable will
load the library that defines the mode. For example:
;;;###autoload (defcustom msb-mode nil "Toggle msb-mode. Setting this variable directly does not take effect; use either \\[customize] or the function `msb-mode'." :set 'custom-set-minor-mode :initialize 'custom-initialize-default :version "20.4" :type 'boolean :group 'msb :require 'msb)
Next: Keymaps and Minor Modes, Up: Minor Modes [Contents][Index]